#include <linux/init.h>
#include <linux/module.h>
#include <linux/netfilter_ipv4.h>
#include <linux/netfilter_bridge/ebtables.h>
#include <net/ip.h>
#include "nf_hook.h"
#include "uf_ipv4.h"

unsigned int UF_forward_entry(unsigned int hook, struct sk_buff *skb,
                                 const struct net_device *in,
                                 const struct net_device *out,
                                 int (*okfn)(struct sk_buff *))
{
    unsigned int ret = NF_ACCEPT;
    struct iphdr *iph = ip_hdr(skb);

    if ((IPPROTO_UDP == iph->protocol) ||
        (IPPROTO_TCP == iph->protocol))
    {
        ret = UF4_filter(skb);
    }

    return ret;
}

struct nf_hook_ops UF_NF_hookfunc[] = {	
	{
		.hook = UF_forward_entry,
		.owner = THIS_MODULE,
		.pf = NFPROTO_IPV4,
		.hooknum = NF_INET_PRE_ROUTING,
		.priority = NF_IP_PRI_FIRST,
	},
	{
		.hook = UF_forward_entry,
		.owner = THIS_MODULE,
		.pf = NFPROTO_IPV4,
		.hooknum = NF_INET_LOCAL_IN,
		.priority = NF_IP_PRI_FIRST,
	},
	{
		.hook = UF_forward_entry,
		.owner = THIS_MODULE,
		.pf = NFPROTO_IPV4,
		.hooknum = NF_INET_FORWARD,
		.priority = NF_IP_PRI_FIRST,
	},
	{
		.hook = UF_forward_entry,
		.owner = THIS_MODULE,
		.pf = NFPROTO_IPV4,
		.hooknum = NF_INET_LOCAL_OUT,
		.priority = NF_IP_PRI_FIRST,
	},
	{
		.hook = UF_forward_entry,
		.owner = THIS_MODULE,
		.pf = NFPROTO_IPV4,
		.hooknum = NF_INET_POST_ROUTING,
		.priority = NF_IP_PRI_FIRST,
	},  
};

int UF_NF_hook(void)
{
    printk(KERN_EMERG"Register Netfilter Hook\r\n");
    nf_register_hooks(UF_NF_hookfunc, ARRAY_SIZE(UF_NF_hookfunc));
    return 0;
}

void UF_NF_unhook(void)
{
    printk(KERN_EMERG"UnRegister Netfilter Hook\r\n");
    nf_unregister_hooks(UF_NF_hookfunc, ARRAY_SIZE(UF_NF_hookfunc));
    return ;
}
